/*
 * XmlMapSaver.java
 *
 * Created on 3. Februar 2007, 12:14
 *
 * Copyright (c) 2007 Daniel Gronau
 *
 * This file is part of KanjiTori.
 *
 * KanjiTori is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * KanjiTori is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

package kanjitori.map;

import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import kanjitori.map.tile.Tile;

/**
 *
 * @author Pirx
 */
public class XmlMapSaver {
    
    private static final XmlMapSaver INSTANCE = new XmlMapSaver();
    private FileWriter writer;
    private DefaultMap map;
    
    
    /** Creates a new instance of XmlMapSaver */
    private XmlMapSaver() {
    }
    
    public static XmlMapSaver getSaver() {
        return INSTANCE;
    }
    
    public void save(String fileName, Map map) {
        this.map = (DefaultMap) map;
        try {
            writer = new FileWriter(fileName);
            writeMap();
            writer.flush();
            writer.close();
            writer = null;
            map = null;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    private void writeMap() throws IOException {
        writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        writer.write(String.format("<map  name=\"%s\" minBots=\"5\" maxBots=\"30\" startBots=\"10\" x=\"%d\" y=\"%d\">\n",
                map.getName(), map.getSize().x(), map.getSize().y()));
        writeRenderstates();
        writeTiles();
        writeLayers();
        writeContents();
        writeSkyBox();
        writer.write("</map>\n");
    }
    
    private void writeLayers() throws IOException {
        writer.write("<layers>\n");
        for (int i = 0; i < map.getLayerCount(); i++) {
            Layer l = map.getLayer(i);
            writer.write(String.format(Locale.ENGLISH, " <layer name=\"%s\" height=\"%f\">\n",
                    l.getName(), l.getHeight()));
            writeLayerLines(l);
            writer.write(" </layer>");
        }
        writer.write("</layers>\n");
    }
    
    private void writeRenderstates() {
        
    }
    
    private void writeTiles() throws IOException {
        java.util.Map<String, Tile> tileMap = new HashMap<String, Tile>();
        for(int l = 0; l < map.getLayerCount(); l++) {
            Layer layer = map.getLayer(l);
            for (int x = 0; x < map.getSize().x(); x++) {
                for (int y = 0; y < map.getSize().y(); y++) {
                    Tile t = layer.getTile(Position.get(x,y));
                    if (t != null) {
                        tileMap.put(t.getName(), t);
                    }
                }
            }
        }
        writer.write("<tiledefs>\n");
        for (java.util.Map.Entry<String, Tile> e : tileMap.entrySet()) {
            writer.write(String.format(" <tiledef name=\"%s\" class=\"%s\">\n",
                    e.getKey(), e.getValue().getClass().getName()));
            java.util.Map<String, String> params = e.getValue().getParams();
            for (java.util.Map.Entry<String, String> pe : params.entrySet()) {
                writer.write(String.format("  <param key=\"%s\" value=\"%s\"/>\n",
                        pe.getKey(), pe.getValue()));
            }
            writer.write(" </tiledef>\n");
        }
        writer.write("</tiledefs>\n");
    }
    
    private void writeLayerLines(Layer layer) throws IOException {
        for (int x = 0; x < map.getSize().x(); x++) {
            for (int y = 0; y < map.getSize().y(); y++) {
                Tile t = layer.getTile(Position.get(x, y));
                if (t != null) {
                    writer.write(String.format("  <tile name=\"%s\" x=\"%d\" y=\"%d\"/>\n",
                            t.getName(), x, y));
                }
            }
        }
    }
    
    private void writeContents() throws IOException {
        writer.write("<contents>\n");
        for (int x = 0; x < map.getSize().x(); x++) {
            for (int y = 0; y < map.getSize().y(); y++) {
                if (map.getContentMatrix().getContent(Position.get(x,y)) != Content.EMPTY) {
                    writer.write(String.format(" <cont x=\"%d\" y=\"%d\"/>\n",
                            x, y));
                }
            }
        }
        writer.write("</contents>\n");
    }
    
    private void writeSkyBox() throws IOException {
        writer.write(String.format("<skybox north=\"%s\" south=\"%s\" east=\"%s\" west=\"%s\" up=\"%s\"  down=\"%s\"/>\n",
                   (Object[]) map.getSkyboxTextures()));
    }
}
